﻿#ifndef WRWORKSERVICELISTMODEL
#define WRWORKSERVICELISTMODEL

#include <QEvent>
#include <QRunnable>
#include <QModelIndex>
#include <QAbstractItemModel>
#include "../WRSoft-Working-Common/Structs/WRWorkStatus.h"
#include "../WRSoft-Working-Common/Structs/WRWorkSwitch.h"
#include "../WRSoft-Working-Common/WRWorkObject.h"
#include "../WRSoft-Utility/WRObjRef.h"

//表示工作服务列表项目。
class WRWorkServiceListEntry : protected WRStateHandler
{
protected:
    int m_index;
    WRWorkStatus m_status;
    WRWorkObject* m_target;
    QString m_uuid;
    bool m_controllable;

    WRTaskDealer* m_switchDealer;
    WRStateSource* m_statusSource;

    //当状态改变后调用此方法。
    void doProcess(const void* value);

public:
    //初始化工作服务列表项目。
    WRWorkServiceListEntry(int index, WRWorkObject* target);
    //清理当前对象所占用的相关资源。
    virtual ~WRWorkServiceListEntry(void);

    //执行初始化。
    void initilize(void);

    //设置为活动。
    void activate(void);
    //设置为不活动。
    void inactivate(void);

    //执行启动操作。
    inline void start()
    {
        WRWorkSwitch task(WRWorkSwitch::Start);
        m_switchDealer->doProcess(&task);
    }
    //执行停止操作。
    inline void stop()
    {
        WRWorkSwitch task(WRWorkSwitch::Stop);
        m_switchDealer->doProcess(&task);
    }

    //获取索引号。
    inline int index(void) const
    {
        return m_index;
    }

    //获取目标对象。
    inline WRWorkObject* target(void) const
    {
        return m_target;
    }

    //获取状态。
    inline WRWorkStatus status(void) const
    {
        return m_status;
    }

    //设置状态。
    inline bool status(WRWorkStatus value)
    {
        if (value != m_status)
        {
            m_status = value;
            return true;
        }
        return false;
    }

    //获取状态文本。
    inline QString statusString(void) const
    {
        return WRText::toString(m_status);
    }

    //获取服务的标识。
    inline const QUuid& uuid(void) const
    {
        return m_target->uuid();
    }
    //获取服务的标识文本。
    inline const QString& uuidString(void) const
    {
        return m_uuid;
    }

    //获取服务的名称。
    inline const QString& title(void) const
    {
        return m_target->title();
    }
    //获取服务的描述。
    inline const QString& description(void) const
    {
        return m_target->description();
    }

    //获取服务是否可以控制。
    inline bool controllable(void) const
    {
        return m_controllable;
    }
};

//声明工作服务列表模型。
class WRWorkServiceListModel;
//表示工作本地服务列表项目。
class WRWorkLocalServiceListEntry : public WRWorkServiceListEntry
{
private:
    WRWorkServiceListModel* m_parent;

protected:
    //当状态改变后调用此方法。
    void doProcess(const void* value);

public:
    //初始化工作服务列表项目。
    WRWorkLocalServiceListEntry(int index, WRWorkObject* target, WRWorkServiceListModel* parent);
};

//声明工作远程服务列表数组。
class WRWorkRemoteServiceListArray;
//表示工作远程服务列表项目。
class WRWorkRemoteServiceListEntry : public WRWorkServiceListEntry
{
private:
    WRWorkRemoteServiceListArray* m_parent;

protected:
    //当状态改变后调用此方法。
    void doProcess(const void* value);

public:
    //初始化工作服务列表项目。
    WRWorkRemoteServiceListEntry(int index, WRWorkObject* target, WRWorkRemoteServiceListArray* parent);
};

//表示工作远程服务列表数组。
class WRWorkRemoteServiceListArray : public QObject
{
private:
    WRWorkServiceListModel* m_parent;
    WRWorkSession* m_session;
    WRArray<WRWorkServiceListEntry*> m_list;
    QMutex m_mutex;
    bool m_init;

    //释放当前对象。
    virtual ~WRWorkRemoteServiceListArray(void);

public:
    //初始化当前数组。
    WRWorkRemoteServiceListArray(WRWorkServiceListModel* parent, WRWorkSession* session, const WRArray<WRWorkObject*>& items);

    //获取集合。
    inline const WRArray<WRWorkServiceListEntry*>& list(void) const
    {
        return m_list;
    }

    //执行初始化。
    void init(void);
    //处理事件。
    bool event(QEvent *);
    //释放当前对象。
    void release(void);
};

//表示工作远程服务列表线程处理者。
class WRWorkRemoteServiceListThreadWorker : public QRunnable
{
private:
    WRWorkRemoteServiceListArray* m_array;

public:
    //初始化处理者。
    WRWorkRemoteServiceListThreadWorker(WRWorkRemoteServiceListArray* array)
    {
        m_array = array;
    }

    //线程池执行方法。
    void run(void)
    {
        m_array->init();
    }
};

//表示工作服务列表模型。
class WRWorkServiceListModel : public QAbstractItemModel, private WRWorkDomain::Watcher
{
    Q_OBJECT

    friend class WRWorkRemoteServiceListArray;

signals:
    //当状态改变后引发此信号（远程工作服务列表模型特有）。
    void statusChanged(void);

private:
    WRArray<WRWorkServiceListEntry*> m_list;
    WRWorkRemoteServiceListArray* m_array;
    WRWorkDomain* m_domain;
    bool m_active;
    WRWorkDomain::Status m_status;

    //设置状态。
    void setStatus(int index, WRWorkStatus value);

    //当工作域状态改变后调用此方法，如果为在线状态，则存在会话，否则会话为0。
    void onChanged(WRWorkDomain* domain, WRWorkDomain::Status status, WRWorkSession* session);

    //清理当前对象所占用的相关资源。
    ~WRWorkServiceListModel(void);

public:
    //初始化本地工作服务列表模型。
    explicit WRWorkServiceListModel(const WRArray<WRWorkObject*>& objects);
    //初始化远程工作服务列表模型。
    explicit WRWorkServiceListModel(WRWorkDomain* domain);

    //设置为活动。
    void activate(void);
    //设置为不活动。
    void inactivate(void);

    //获取域状态（远程工作服务列表模型特有）。
    inline WRWorkDomain::Status status(void) const
    {
        return m_status;
    }

    //获取数量。
    inline int count(void) const
    {
        return (WR32s)m_list.count();
    }
    //获取指定行的项目。
    inline WRWorkServiceListEntry* index(int row) const
    {
        return m_list[row];
    }

    //处理事件。
    bool event(QEvent *);

    //判断是否存在索引。
    bool hasIndex(int row, int column, const QModelIndex &parent = QModelIndex());

    //获取索引。
    QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;

    //获取父索引。
    QModelIndex parent(const QModelIndex &child) const;

    //获取行数量。
    int rowCount(const QModelIndex &parent = QModelIndex()) const;
    //获取列数量。
    int columnCount(const QModelIndex &parent = QModelIndex()) const;

    //判断是否具有子级。
    bool hasChildren(const QModelIndex & parent = QModelIndex()) const;

    //获取内容数据。
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
    //获取标题数据。
    QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
};

#endif // WRWORKSERVICELISTMODEL

